import type { Context, Next, RequestOptions } from './core/context'
import type { IHookArg, Method } from './core/router'
import type { SchemaField } from './core/verify'

export { default } from './core/index'
export { default as Easy } from './core/index'
export { isAsyncFunction, LRUCache } from './core/utils'

type DefaultStateExtends = any
/**
 * 默认状态
 */
export interface CustomState extends DefaultStateExtends { }

interface DefaultContextExtends { }

/**
 * 自定义上下文
 */
export interface CustomContext extends DefaultContextExtends {
  // 用户可以扩展此接口以添加自定义属性
  /**
   * 自定义
   */
  [key: PropertyKey]: any
}

type ExtractSchemaType<T extends Record<string, TSchema>> = {
  [K in keyof T]: T[K]['type'] extends 'string' ? string
    : T[K]['type'] extends 'number' ? number
      : T[K]['type'] extends 'boolean' ? boolean : never; // 按需扩展其他类型
}

interface ExpandContext<T extends SchemaDefine> extends Context<CustomState, CustomContext> {
  query: T['query'] extends Record<string, TSchema>
    ? ExtractSchemaType<T['query']>
    : object
  params: T['params'] extends Record<string, TSchema>
    ? ExtractSchemaType<T['params']>
    : object
  body: T['body'] extends Record<string, TSchema>
    ? ExtractSchemaType<T['body']>
    : object
}

type _Combine<T extends string, U extends string = T>
    = T extends any
      ? T | `${T}|${_Combine<Exclude<U, T>>}`
      : never

type HandlerConfig<T extends SchemaDefine> = (this: ExpandContext<T>, ctx: ExpandContext<T>, request: RequestOptions) => Promise<void> | void
interface ServiceConfig<T extends SchemaDefine = SchemaDefine> {
  /** @description 是否禁用该接口 */
  disabled?: boolean
  /** @description 是否禁用该接口的schema验证 */
  disabledVerify?: boolean
  /** @description 请求方法 */
  method?: _Combine<Method>
  schema?: T
  /** @description 前置拦截器 */
  onRequest?: IHookArg
  /** @description 后置拦截器 */
  onResponse?: IHookArg
  /** @description 错误拦截器 */
  onError?: (err: Error, ctx: Context, next: Next) => Promise<any> | any
  /** @description 业务处理函数 */
  handler: HandlerConfig<T>
}

export function defineService<T extends SchemaDefine = SchemaDefine>(config: ServiceConfig<T>) {
  return config
}
type TSchema = SchemaField<'number' | 'string' | 'object' | 'array' | 'boolean'>
export interface SchemaDefine {
  /** @description 接口描述 */
  desc?: string
  query?: {
    [key: string]: TSchema
  }
  params?: {
    [key: string]: TSchema
  }
  body?: {
    [key: string]: TSchema
  }
  response?: {
    [key: string]: TSchema
  }
}

export function defineSchema<S extends SchemaDefine>(schema: S): S {
  return schema
}

// 添加模块增强声明，允许用户在自己的项目中扩展CustomContext接口
declare module './index' {
  interface CustomContext {
    // 这里可以添加自定义的上下文属性
  }
  interface CustomState {
    // 这里可以添加自定义的状态属性
  }
}
